package com.info.zhiduoduo.common.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EasyExcelUtil {

	/**
	 * @param response
	 * @param fileName 文件名,不需要xlsx文件格式后缀.会自动拼接.
	 * @param clazz
	 * @param list
	 * @param <T>
	 */
	public static <T> void download(HttpServletResponse response, String fileName, Class<T> clazz, List<T> list) {
		try {
			response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
			EasyExcel.write(getExcelOutPutStream(response, fileName), clazz)
					 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
					 .sheet()
					 .doWrite(list);
		} catch (Exception e) {
			e.printStackTrace();
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	/**
	 * 下载需要填充复杂模板的表格
	 *
	 * @param response
	 * @param templatePath
	 * @param fileName     文件名,不需要xlsx文件格式后缀.会自动拼接.
	 * @param list         列表数据
	 * @param map          表格特殊字段的值.
	 * @param <T>
	 */
	public static <T> void downloadComplex(HttpServletResponse response, String templatePath, String fileName, List<T> list,
	                                       Map<String, Object> map) {
		try {
			response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
			ExcelWriter excelWriter = EasyExcel.write(getExcelOutPutStream(response, fileName)).excelType(ExcelTypeEnum.XLSX).withTemplate(templatePath).build();
			// 创建 Sheet
			WriteSheet writeSheet = EasyExcel.writerSheet().build();
			// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。
			// 默认 是false，会直接使用下一行，如果没有则创建。但是这个就会把所有数据放到内存 会很耗内存
			// FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
			excelWriter.fill(list, null, writeSheet);
			excelWriter.fill(map, writeSheet);
			excelWriter.finish();
		} catch (Exception e) {
			log.error("导出塾人项目模板报错", e);
			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
		}
	}

	/**
	 * 下载需要填充复杂模板的表格
	 *
	 * @param response
	 * @param templatePath
	 * @param fileName     文件名
	 * @param list         列表数据
	 * @param <T>
	 */
	public static <T> void exportComplex(HttpServletResponse response, String templatePath, String fileName, List<T> list) throws Exception {
		ExcelWriter excelWriter = EasyExcel.write(getExcelOutPutStream(response, fileName)).withTemplate(templatePath).build();
		WriteSheet writeSheet = EasyExcel.writerSheet().build();
		FillConfig fillConfig = FillConfig.builder().build();
		excelWriter.fill(list, fillConfig, writeSheet);
		excelWriter.fill(null, writeSheet);
		excelWriter.finish();
	}

	/**
	 * 获取输出流，并设置下载excel的header
	 *
	 * @param response
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static OutputStream getExcelOutPutStream(HttpServletResponse response, String file) throws Exception {
		// 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
		String fileName = URLEncoder.encode(file, "UTF-8");
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		return response.getOutputStream();
	}
}
